]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
brightnessManager: Handle dimming and auto brightness
authorSebastian Wick <sebastian.wick@redhat.com>
Sat, 21 Jun 2025 22:06:27 +0000 (00:06 +0200)
committerSebastian Wick <sebastian.wick@redhat.com>
Sun, 3 Aug 2025 01:34:28 +0000 (03:34 +0200)
We don't want gnome-settings-daemon to poke directly at mutters
backlight anymore because that would be a split brain situation where
g-s and g-s-d will fight with each other. This implements a way to tell
the BrightnessManager to dim the screen and set an auto brightness
target, and the manager will set the backlight accordingly.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3751>

js/misc/brightnessManager.js
js/ui/status/brightness.js

index 2e7cc5b2bd70aa6cd45fea923dc93937a7d6b33f..9d6fe16e8cb0b1070348b4812f1f2e4e97799005 100644 (file)
@@ -5,6 +5,8 @@ import * as Main from '../ui/main.js';
 
 const SCALE_VALUE_CHANGE_EPSILON = 0.001;
 
+const POWER_SCHEMA = 'org.gnome.settings-daemon.plugins.power';
+
 export const BrightnessManager = GObject.registerClass({
     Signals: {
         'changed': {},
@@ -16,12 +18,38 @@ export const BrightnessManager = GObject.registerClass({
         this._globalScale = null;
         this._monitorScales = new Map();
 
+        // This is still being used in the power plugin for the keyboard backlight
+        // so we just use that setting here
+        const powerSettings = new Gio.Settings({schema_id: POWER_SCHEMA});
+        this._dimmingTarget = powerSettings.get_int('idle-brightness') / 100;
+        this._dimmingEnabled = false;
+
+        this._abTarget = -1.0;
+
         const monitorManager = global.backend.get_monitor_manager();
         monitorManager.connectObject('monitors-changed',
             this._monitorsChanged.bind(this), this);
         this._monitorsChanged();
     }
 
+    get dimming() {
+        return this._dimmingEnabled;
+    }
+
+    set dimming(enable) {
+        this._dimmingEnabled = enable;
+        this._sync();
+    }
+
+    get autoBrightnessTarget() {
+        return this._abTarget;
+    }
+
+    set autoBrightnessTarget(target) {
+        this._abTarget = target;
+        this._sync();
+    }
+
     get globalScale() {
         return this._globalScale;
     }
@@ -81,8 +109,13 @@ export const BrightnessManager = GObject.registerClass({
         this._inhibitUpdates = true;
 
         // Handle changed backlights
-        for (const scale of this._monitorScales.values())
-            scale.syncWithBacklight();
+        for (const scale of this._monitorScales.values()) {
+            if (scale.syncWithBacklight()) {
+                // disable dimming for all if we have a single system initiated
+                // backlight change
+                this._dimmingEnabled = false;
+            }
+        }
 
         // Find scales which have been changed (and reset _scaleChanged)
         const changedScales = [...this._monitorScales.values()].filter(s => {
@@ -124,9 +157,18 @@ export const BrightnessManager = GObject.registerClass({
                 this._showOSD(this._monitorScales.values());
         }
 
+        // ensure we lock the global scale when auto brightness is in control
+        this._globalScale.locked = this._abTarget >= 0.0;
+
         // Update the actual backlight according to the new monitor brightnesses
-        for (const scale of this._monitorScales.values())
-            scale.setBacklight(scale.value);
+        // and other factors, such as dimming.
+        for (const scale of this._monitorScales.values()) {
+            const max = this._dimmingEnabled ? this._dimmingTarget : 1.0;
+            const target = this._abTarget >= 0.0 ? this._abTarget : scale.value;
+            const brightness = Math.min(max, target);
+
+            scale.setBacklight(brightness);
+        }
 
         this._inhibitUpdates = false;
     }
@@ -152,11 +194,16 @@ export const BrightnessScale = GObject.registerClass({
             'value', null, null,
             GObject.ParamFlags.READWRITE,
             0, 1.0, 1.0),
+        'locked': GObject.ParamSpec.boolean(
+            'locked', null, null,
+            GObject.ParamFlags.READWRITE,
+            false),
     },
 }, class BrightnessScale extends GObject.Object {
     constructor(name, value) {
         super({
             value,
+            locked: false,
         });
 
         this._name = name;
@@ -174,6 +221,17 @@ export const BrightnessScale = GObject.registerClass({
         this._setValue(value);
     }
 
+    get locked() {
+        return this._locked;
+    }
+
+    set locked(locked) {
+        if (this._locked === locked)
+            return;
+        this._locked = locked;
+        this.notify('locked');
+    }
+
     _setValue(value) {
         value = Math.clamp(value, 0.0, 1.0);
         if (Math.abs(value - this._value) < SCALE_VALUE_CHANGE_EPSILON)
index 768186af37cc8ff721e87a2dc0cf425084a725a4..d4e57f1cabbc4e551a81c3506b98531b0d898a7c 100644 (file)
@@ -16,6 +16,13 @@ class BrightnessItem extends QuickSlider {
 
         this._manager = Main.brightnessManager;
         this._manager.connectObject('changed',
+            this._onManagerChanged.bind(this), this);
+        this._onManagerChanged();
+    }
+
+    _onManagerChanged() {
+        this._manager.globalScale?.disconnectObject(this);
+        this._manager.globalScale?.connectObject('notify::locked',
             this._sync.bind(this), this);
         this._sync();
     }
@@ -23,7 +30,7 @@ class BrightnessItem extends QuickSlider {
     _sync() {
         const {globalScale} = this._manager;
         this.set({
-            visible: !!globalScale,
+            visible: globalScale && !globalScale.locked,
         });
 
         if (!this.visible)